package org.ecpkn.PAGridSim.core.tasksCreation;

import java.util.ArrayList;

import org.ecpkn.PAGridSim.core.configuration.Configuration;

/**
 * @author Lin Zhou
 * 
 *         Module:Tasks Creation
 * 
 */
public class Task {

	// Repeat a job for "repeatNumber" times in the task
	// repeat time limited at REPEATLIMIT in order not to get an id in conflit
	private static int REPEATLIMIT = Configuration.getInstance()
			.getParameterInt(Configuration.Const.TASK_REPEAT_LIMIT);
	private double period_;
	private double length_;
	// only one submited time for all the jobs in the task
	private double submitedTime_;
	private ArrayList<Job> jobs_;
	private int repeatNumber_;
	private int taskID_;

	/**
	 * Constructor of the class Task
	 * 
	 * @param taskID
	 *            the taskID consists of the experimentRepeatNumber and the real
	 *            task number
	 * @param period
	 * @param length
	 *            the CPU instructions needed for a job of the task
	 * @param submitedTime
	 *            the moment when the task will be submitted to the scheduler
	 * @param repeatNumber
	 *            the number of jobs that the task consists of
	 * @throws Exception
	 */
	public Task(int taskID, double period, double length, double submitedTime,
			int repeatNumber) throws Exception {
		this.taskID_ = taskID;
		this.period_ = period;
		this.length_ = length;
		this.submitedTime_ = submitedTime;
		this.repeatNumber_ = repeatNumber;
		jobs_ = createJobs();
	}

	public int getTaskID_() {
		return taskID_;
	}

	/**
	 * the jobId can be defined with different method.We can change the formula
	 * 
	 * @param repeatNumber
	 *            the jobIds of the same task are distinguished by its'
	 *            repeatNumber
	 * @return jobId
	 */
	private int defineJobId(int repeatNumber) {
		// a task should not repeat more than REPEATLIMIT times jobs,otherwise,
		// this formula could make the same id for different
		// tasks.Example:110001 can represent the 1 job of the task number 11 or
		// the 10001 job of the task number 10
		return taskID_ * REPEATLIMIT + repeatNumber;
	}

	/**
	 * 
	 * @return jobs instances of this task
	 * @throws Exception
	 */
	private ArrayList<Job> createJobs() throws Exception {
		ArrayList<Job> jobs = new ArrayList<Job>();
		int jobID = 0;
		if (repeatNumber_ > REPEATLIMIT - 1) {
			throw new Exception(
					"Task.createJobs:The task repeatNumber should not be greater than what you put in the config.xml file(Task_Repeat_Limit)");
		}
		for (int i = 0; i < repeatNumber_; i++) {
			jobID = defineJobId(i);
			jobs.add(new Job(jobID, this, i));
		}
		return jobs;
	}

	public ArrayList<Job> getJobs_() {
		return jobs_;
	}

	public double getPeriod_() {
		return period_;
	}

	public double getLength_() {
		return length_;
	}

	public double getSubmitedTime_() {
		return submitedTime_;
	}

	public double getEndTime() {
		return submitedTime_ + repeatNumber_ * period_;
	}

	public double getUtilization(double frequency) {
		return length_ / frequency / period_;
	}

	public int getRepeatNumber_() {
		return repeatNumber_;
	}

}
